package com.mlink.ai.chat.ui.activity

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Vibrator
import android.text.Editable
import android.text.InputFilter.LengthFilter
import android.text.TextUtils
import android.text.TextWatcher
import android.util.Log
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.core.content.FileProvider
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.adsdk.android.ads.rewarded.AdReward
import com.adsdk.android.ads.rewarded.RewardedAdListener
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.mlink.ai.chat.AiChatApplication
import com.mlink.ai.chat.ads.AdUtils
import com.mlink.ai.chat.ads.chatRewardCache
import com.mlink.ai.chat.assistant.robot.R
import com.mlink.ai.chat.assistant.robot.databinding.ActivityChatBinding
import com.mlink.ai.chat.constants.EXTRA_FROM_PROMPT_NOTIFICATION
import com.mlink.ai.chat.constants.EXTRA_PROMPT_CATEGORY_EVENT_NAME
import com.mlink.ai.chat.constants.EXTRA_PROMPT_SUBCATEGORY_EVENT_NAME
import com.mlink.ai.chat.constants.KEY_CHAT_EXAMPLE
import com.mlink.ai.chat.constants.KEY_CHAT_PROMPT
import com.mlink.ai.chat.constants.MYSELF_URL_IN_GOOGLE_PLAY
import com.mlink.ai.chat.local.entity.ChatMessageEntity
import com.mlink.ai.chat.network.bean.response.GetAnswerResponse
import com.mlink.ai.chat.ui.adapter.ChatItem
import com.mlink.ai.chat.ui.adapter.ChatRecyclerAdapter
import com.mlink.ai.chat.ui.adapter.ChatType
import com.mlink.ai.chat.ui.fragment.EnsureExitDialogFragment
import com.mlink.ai.chat.ui.fragment.FeedbackDialogFragment
import com.mlink.ai.chat.ui.fragment.RewardDialogFragment
import com.mlink.ai.chat.ui.fragment.SelectPhotoBottomDialogFragment
import com.mlink.ai.chat.ui.fragment.SelectShareBottomDialogFragment
import com.mlink.ai.chat.ui.viewmodel.ChatViewModel
import com.mlink.ai.chat.ui.viewmodel.RecentViewModel
import com.mlink.ai.chat.utils.AnalyticsEvents
import com.mlink.ai.chat.utils.AnalyticsParams
import com.mlink.ai.chat.utils.BitmapUtils
import com.mlink.ai.chat.utils.ChatLimitUtils
import com.mlink.ai.chat.utils.FileUtils
import com.mlink.ai.chat.utils.GooglePlayCore
import com.mlink.ai.chat.utils.SoftKeyboardHelper
import com.mlink.ai.chat.utils.logEvent
import com.tencent.mmkv.MMKV
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File


class ChatActivity : BaseActivity<ActivityChatBinding>() {

    private lateinit var chatAdapter: ChatRecyclerAdapter
    private val viewModel: ChatViewModel by lazy {
        ViewModelProvider(this)[ChatViewModel::class.java]
    }
    private val recentViewModel: RecentViewModel by viewModels()
    private var isLoading = false
    private var ensureDialogFragment: EnsureExitDialogFragment? = null
    private val softKeyboardHelper by lazy { SoftKeyboardHelper(this@ChatActivity) }
    private var isKeyboardVisible = false  // 是否展示软键盘
    private var isHandleShare = false // 是否正在生成分享的图片
    private var isGoingToBilling = false //是否马上要去订阅界面
    private var isSubscribe = false //是否订阅了
    private var rewardDialogFragment: RewardDialogFragment? = null
    private var photoFrom: String? = null
    private var selectDialogFragment: SelectPhotoBottomDialogFragment? = null
    private var feedbackDialogFragment: FeedbackDialogFragment? = null
    private var selectPhotoPath: String? = null
    private var selectShareFragment: SelectShareBottomDialogFragment? = null
    private var isOpen =false
    private var chatContent = StringBuffer()

    private val billingActivityResultLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (!AiChatApplication.app.appViewModel.isSubscribed()) {
                chatAdapter.notifyLimitsItemChanged(showAdLimits = true, isLoading = false)
            }
        }

    private val destroyCallback = Runnable {
        rewardDialogFragment?.setIsAdLoad(false)
        chatAdapter.notifyLimitsItemChanged(showAdLimits = true, isLoading = false)

        chatRewardCache.destroyAd()
        Toast.makeText(
            this@ChatActivity,
            resources.getString(R.string.reward_fail),
            Toast.LENGTH_LONG
        ).show()
    }


    override fun getViewBinding(): ActivityChatBinding {
        return ActivityChatBinding.inflate(layoutInflater)
    }

    override fun initViews() {
        binding.etChat.post {
            setSendClickable(false)
            setShareClickable(false)
        }
        initializeToolbar()
        initializeChatRecycler()
        initializeChatEdit()
        initializeRegenerate()
        initializePhoto()
        initNewChatData()

        if (chatRewardCache.mRewardedAdHelper == null && !AiChatApplication.app.appViewModel.isSubscribed()) {
            chatRewardCache.initRewardAdHelper(this)
        }
        viewModel.lastChatItem.observe(this) {
            chatAdapter.addMessage(it)
            isLoading = false
            if (binding.etChat.text.isNotEmpty() && !chatAdapter.isLastAnswerIsLimits()) {
                setSendClickable(true)
            }
            showLatestRemain()
            if (it.type == ChatType.TYPE_ANSWER && !it.isLoading &&
                MMKV.defaultMMKV().decodeInt(GooglePlayCore.KEY_NUM_SHOW_REVIEW) < 3
            ) {
                GooglePlayCore.launchGooglePlay(this)
            }
            if (it.type == ChatType.TYPE_ANSWER && !it.isLoading) {
                setShareClickable(true)
            }
        }


        viewModel.errorMsgEvent.observe(this) {
            if (MMKV.defaultMMKV().decodeBool(AboutActivity.KEY_IS_OPEN_ERROR_TOAST)) {
                Toast.makeText(this, it, Toast.LENGTH_LONG).show()
            }
        }

        AiChatApplication.app.appViewModel.getSubscribeLiveData().observe(this) {
            val filter = LengthFilter(if (it) 1000 else 500)
            binding.etChat.filters = arrayOf(filter)
            isSubscribe = it
            binding.tvRemain.isVisible = !it
            binding.rlActionReward.isVisible = !it

            if (it && !chatAdapter.isLimitsEmpty()) {
                chatAdapter.removeAllLimits()
                doRegenerate()
            }
        }

        AnalyticsEvents.AC_CHATAI_PAGE_SHOW.logEvent()
    }

    override fun onResume() {
        super.onResume()
        val isSubscribed = AiChatApplication.app.appViewModel.getSubscribeLiveData().value ?: false
        if ((isSubscribed || !ChatLimitUtils.isUpToLimit()) &&
            !chatAdapter.isLimitsEmpty()
        ) {
            chatAdapter.removeAllLimits()
            doRegenerate()
        }
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)

        val prompt = intent?.getStringExtra(KEY_CHAT_PROMPT) ?: ""
        if (prompt.isNotEmpty()) {
            binding.etChat.setText(prompt)
        }

        logPromptNotificationClickEvent(intent)
    }

    private fun logPromptNotificationClickEvent(intent: Intent?) {
        val fromPromptNotification =
            intent?.getBooleanExtra(EXTRA_FROM_PROMPT_NOTIFICATION, false) ?: false
        if (fromPromptNotification) {
            val categoryEventName = intent?.getStringExtra(EXTRA_PROMPT_CATEGORY_EVENT_NAME)
            val subCategoryEventName = intent?.getStringExtra(EXTRA_PROMPT_SUBCATEGORY_EVENT_NAME)
            AnalyticsEvents.AC_PUSH_PPT_CLICK.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.CATEGORY, categoryEventName)
                    putString(AnalyticsParams.KEY_TITLE, subCategoryEventName)
                }
            )
        }
    }

    @OptIn(DelicateCoroutinesApi::class)
    override fun onPause() {
        super.onPause()
        if (isFinishing) {
            if (chatAdapter.getHistoryEntity() != null) {
                recentViewModel.insertHistoryMessage(entity = chatAdapter.getHistoryEntity())
            } else {
                GlobalScope.launch(Dispatchers.IO) {
                    runCatching {
                        chatAdapter.data.forEach {
                            val path = it.content?.imagePath
                            if (!TextUtils.isEmpty(path)) {
                                val file = File(path!!)
                                if (file.exists()) {
                                    file.delete()
                                }
                            }
                        }
                        ChatMessageEntity.removeTempPic()
                    }
                }
            }
        }
    }

    override fun onBackPressed() {
        AnalyticsEvents.AC_CHATAI_EXIT_CLICK.logEvent()
        if (isGoingToBilling) return
        if (chatAdapter.isQuestionEmpty()) {
            super.onBackPressed()
            return
        }
        doShowEnsureExitDialog()
    }

    fun initNewChatData(){
        viewModel.isOpenData.observe(this){
            isOpen = it
            if(isOpen){
                chatContent = StringBuffer()
            }
        }
        viewModel.chatReceiveData.observe(this){
            if(isOpen){
                if(TextUtils.isEmpty(chatContent)){
                    chatContent.append(it)
                    val chatItem = ChatItem(
                        content = GetAnswerResponse(answer = chatContent.toString() ),
                        ChatType.TYPE_LIMITS,
                        isOpen
                    )
                    viewModel.lastChatItem.value = chatItem
                }else{
                    chatContent.append(it)
                    if(binding.chatRecycler.childCount>0){
                        val view = binding.chatRecycler.getChildAt(binding.chatRecycler.childCount-1)
                        val tv_content = view.findViewById<TextView>(R.id.tv_content)
                        tv_content.text = chatContent.toString()
                    }

                }
            }
        }
    }

    override fun onDestroy() {
        chatRewardCache.destroyAd()
        AnalyticsEvents.AC_CHATAI_EXIT_SUC.logEvent()
        super.onDestroy()
    }

    private fun initializeToolbar() {
        binding.ivBack.setOnClickListener {
            AnalyticsEvents.AC_CHATAI_EXIT_CLICK.logEvent()
            if (isGoingToBilling) return@setOnClickListener
            if (chatAdapter.isQuestionEmpty()) {
                finish()
                return@setOnClickListener
            }
            doShowEnsureExitDialog()
        }

        binding.ivShare.setOnClickListener {
            AnalyticsEvents.AC_CHATAI_HISTORY_SHARE.logEvent()
            selectShareFragment = SelectShareBottomDialogFragment()
            selectShareFragment?.listener =
                object : SelectShareBottomDialogFragment.OnFunctionListener {
                    override fun onTxtClick() {
                        val data = chatAdapter.data
                        val builder = StringBuilder()
                        data.forEach {
                            if (it.type == ChatType.TYPE_QUESTION || it.type == ChatType.TYPE_PHOTO) {
                                val content = it.content?.answer ?: ""
                                builder.append("Q: $content")
                                builder.append("\n\n")
                            } else if (it.type == ChatType.TYPE_ANSWER && !it.isLoading) {
                                val content = it.content?.answer ?: ""
                                builder.append("A: $content")
                                builder.append("\n\n")
                            }
                        }
                        builder.append("${getString(R.string.share_prefix)} $MYSELF_URL_IN_GOOGLE_PLAY")
                        val result = builder.toString()
                        try {
                            val intent = Intent()
                            intent.action = Intent.ACTION_SEND
                            intent.putExtra(Intent.EXTRA_TEXT, result)
                            intent.type = "text/plain"
                            startActivity(Intent.createChooser(intent, "Share to"))
                        } catch (_: Exception) {
                            // do nothing now
                        }
                        selectShareFragment?.dismissAllowingStateLoss()
                    }

                    override fun onPhotoClick() {
                        doShareChat()
                        selectShareFragment?.dismissAllowingStateLoss()
                    }

                }
            selectShareFragment?.show(supportFragmentManager, "")
        }

        binding.rlActionReward.setOnClickListener {
            AnalyticsEvents.AC_CHAT_SUBBUTTON_CLICK.logEvent()

            doShowRewardDialog(false)
        }

        showLatestRemain()
    }

    private fun initializeChatRecycler() {
        chatAdapter = ChatRecyclerAdapter().apply {
            listener = object : ChatRecyclerAdapter.ChatFunctionListener {
                override fun onCopyContent(item: ChatItem) {
                    runCatching {
                        val cbm = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                        item.content?.answer?.let {
                            cbm.setPrimaryClip(ClipData.newPlainText(null, it))
                            val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
                            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
                                Toast.makeText(
                                    this@ChatActivity,
                                    this@ChatActivity.resources.getString(R.string.chat_copied),
                                    Toast.LENGTH_SHORT
                                )
                                    .show()
                            }
                            vibrator.vibrate(100)
                        }
                    }
                }

                override fun onRegenerateVisible(isVisible: Boolean) {
                    binding.llRegenerate.isVisible = isVisible
                }

                override fun onRemoveLimitsShow(isAuto: Boolean, isShowAdLimit: Boolean) {
                    if (isShowAdLimit) {
                        watchRewardAd()
                    } else {
                        val intent = Intent(this@ChatActivity, BillingActivity::class.java).apply {
                            putExtra(BillingActivity.KEY_VIP_TYPE, AnalyticsParams.SEND)
                        }
                        setIsGoingToBilling(false)
                        billingActivityResultLauncher.launch(intent)
                    }
                }

                override fun onGoingToBilling() {
                    setIsGoingToBilling(true)
                }

                override fun onClickGood(item: ChatItem) {
                    GooglePlayCore.launchGooglePlay(this@ChatActivity)
                }

                override fun onClickBad(item: ChatItem) {
                    feedbackDialogFragment = FeedbackDialogFragment()
                    feedbackDialogFragment?.show(supportFragmentManager, "")
                }

                override fun onShareContent(item: ChatItem) {
                    try {
                        val result =
                            "${item.content?.answer ?: ""}\n\n${getString(R.string.share_prefix)} $MYSELF_URL_IN_GOOGLE_PLAY"
                        val intent = Intent()
                        intent.action = Intent.ACTION_SEND
                        intent.putExtra(Intent.EXTRA_TEXT, result)
                        intent.type = "text/plain"
                        startActivity(Intent.createChooser(intent, "Share to"))
                    } catch (_: Exception) {
                        // do nothing now
                    }
                }
            }
        }
        binding.chatRecycler.run {
            layoutManager =
                LinearLayoutManager(this@ChatActivity, LinearLayoutManager.VERTICAL, false)
            adapter = chatAdapter
            setItemViewCacheSize(0)
        }

    }

    private fun initializeChatEdit() {
        binding.run {
            ivSend.setOnClickListener {
                AnalyticsEvents.AC_CHATAI_SENDBTN_CLICK.logEvent()
                if (photoFrom == null) {
//                    doSendQuestion()
                    Log.e("zzzz", "initializeChatEdit: "+chatRecycler.childCount )
//                    viewModel.getAnswer2("user","我爱中国")
                    viewModel.getAnswer3()
                } else {
                    doSendQuestionWithPhoto()
                }
            }
            ivDelete.setOnClickListener { etChat.setText("") }
            etChat.addTextChangedListener(object : TextWatcher {
                override fun beforeTextChanged(
                    s: CharSequence?,
                    start: Int,
                    count: Int,
                    after: Int
                ) {
                }

                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

                override fun afterTextChanged(s: Editable?) {
                    ivDelete.isVisible = etChat.text.isNotEmpty()
                    if (etChat.text.isEmpty() || etChat.text.toString().trim().isEmpty()) {
                        setSendClickable(false)
                    } else {
                        if (!isLoading && !chatAdapter.isLastAnswerIsLimits()) {
                            setSendClickable(true)
                        }
                    }
                    tvLimit.isVisible = etChat.lineCount > 1
                    tvLimit.text =
                        if (isSubscribe) {
                            String.format(
                                resources.getString(R.string.char_limit_1000),
                                etChat.text.length
                            )
                        } else {
                            String.format(
                                resources.getString(R.string.char_limit_500),
                                etChat.text.length
                            )
                        }
                }

            })
            val question = intent?.getStringExtra(KEY_CHAT_EXAMPLE)
            val prompt = intent?.getStringExtra(KEY_CHAT_PROMPT) ?: ""
            etChat.setText(prompt)
            if (question == null || !ChatLimitUtils.isUpToLimit() || prompt.isNotEmpty()) {
                etChat.requestFocus()
            }

            logPromptNotificationClickEvent(intent)

            etChat.post {
                setSendClickable(prompt.isNotEmpty())
                if (question != null) {
                    etChat.setText(question)
                    etChat.setSelection(etChat.text.length)
                    if (ChatLimitUtils.isUpToLimit() && !isSubscribe) {
                        doShowRewardDialog(true)
                    } else {
                        ivSend.performClick()
                    }
                    return@post
                }
                val item = ChatItem(
                    content = GetAnswerResponse(answer = resources.getString(R.string.chat_ai_guide)),
                    ChatType.TYPE_GUIDE,
                    false
                )
                chatAdapter.addMessage(
                    item
                )

                tvLimit.isVisible = etChat.lineCount > 1
                tvLimit.text =
                    if (isSubscribe) {
                        String.format(
                            resources.getString(R.string.char_limit_1000),
                            etChat.text.length
                        )
                    } else {
                        String.format(
                            resources.getString(R.string.char_limit_500),
                            etChat.text.length
                        )
                    }
            }


            softKeyboardHelper.setKeyboardListener(binding.root,
                object : SoftKeyboardHelper.SoftKeyboardListener {
                    override fun onSoftKeyboardShow(softKeyboardHeight: Int) {
                        isKeyboardVisible = true
                        chatAdapter.scrollToBottom()
                    }

                    override fun onSoftKeyboardHide(softKeyboardHeight: Int) {
                        isKeyboardVisible = false
                    }
                })
        }

    }

    private fun initializeRegenerate() {
        binding.llRegenerate.setOnClickListener {
            doRegenerate()
        }
    }

    private fun initializePhoto() {
        intent.getStringExtra(SelectPhotoBottomDialogFragment.KEY_URI)?.let {
            selectPhoto(it)
        }
        intent.getStringExtra(SelectPhotoBottomDialogFragment.KEY_PHOTO_FROM)?.let {
            photoFrom = it
        }
        binding.ivDeletePhoto.setOnClickListener {
            deletePhoto()
        }
        binding.ivSelect.setOnClickListener {
            AnalyticsEvents.AC_CHATAI_ADD_CLICK.logEvent()
            doShowSelectDialogFragment()
        }
    }

    private fun doRegenerate() {
        isLoading = true
        chatAdapter.getLastQuestionContent()?.let { question ->
            chatAdapter.addMessage(
                ChatItem(
                    null,
                    ChatType.TYPE_ANSWER,
                    true
                )
            )
            val errorMsg = resources.getString(R.string.chat_default_errot_msg)
            if (photoFrom != null) {
                viewModel.getAnswerWithPhoto(
                    question,
                    chatAdapter.getLastPhotoPath()?.let { File(it) },
                    chatAdapter.getLastConversationId(),
                    errorMsg
                )
            } else {
                viewModel.getAnswer(question, chatAdapter.getLastConversationId(), errorMsg)
            }
        }
        setSendClickable(false)
    }

    private fun doShowEnsureExitDialog() {
        val isVisible = isKeyboardVisible
        ensureDialogFragment = EnsureExitDialogFragment()
        ensureDialogFragment?.show(supportFragmentManager, "")
        ensureDialogFragment?.listener = object : EnsureExitDialogFragment.OnDialogClickListener {
            override fun onEnsure() {
                finish()
            }

            override fun onCancel() {
                ensureDialogFragment?.dismissNow()
                if (isVisible) {
                    binding.etChat.postDelayed(
                        { softKeyboardHelper.showSoftKeyboard(binding.etChat) }, 300L
                    )
                }
            }

        }
    }

    private fun doShareChat() {
        if (isHandleShare) {
            return
        }
        isHandleShare = true
        lifecycleScope.launch {
            var uri: Uri
            val bitmap = BitmapUtils.shotRecyclerView(binding.chatRecycler)
            if (bitmap == null) {
                isHandleShare = false
                return@launch
            }
            withContext(Dispatchers.IO) {
                val dir = File(FileUtils.getCacheDir(this@ChatActivity), "pic")
                val file = File(dir, "share.jpeg")
                if (!dir.exists()) {
                    dir.mkdirs()
                }
                if (!file.exists() && dir.isFile) {
                    file.createNewFile()
                }
                BitmapUtils.bitmapToFile(bitmap, file)
                uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    FileProvider.getUriForFile(this@ChatActivity, "$packageName.fileprovider", file)
                } else {
                    Uri.fromFile(file)
                }

            }
            try {
                val intent = Intent()
                intent.action = Intent.ACTION_SEND
                intent.putExtra(Intent.EXTRA_STREAM, uri)
                intent.type = "image/*"
                startActivity(Intent.createChooser(intent, "Share to"))
            } catch (_: Exception) {
                // do nothing now
            } finally {
                delay(1500L) //延时保证选择应用底部弹窗完全获取焦点
                isHandleShare = false
            }
        }
    }

    private fun doSendQuestion() {
        val beforeText = binding.etChat.text.toString()
        val finalText = beforeText.trim()
        chatAdapter.addMessage(
            ChatItem(
                GetAnswerResponse(answer = finalText),
                ChatType.TYPE_QUESTION,
                false
            )
        )
        chatAdapter.addMessage(
            ChatItem(
                null,
                ChatType.TYPE_ANSWER,
                true
            )
        )
        isLoading = true
        val errorMsg = resources.getString(R.string.chat_default_errot_msg)
        viewModel.getAnswer(finalText, chatAdapter.getLastConversationId(), errorMsg)
        binding.etChat.setText("")
        setSendClickable(false)
    }

    private fun doSendQuestionWithPhoto() {
        val beforeText = binding.etChat.text.toString()
        val finalText = beforeText.trim()

        val dir = File(FileUtils.getCacheDir(this), "pic")
        var resultFile: File? = null
        if (selectPhotoPath != null) {
            resultFile = File(dir, "${System.currentTimeMillis()}.jpeg")
            if (!dir.exists()) {
                dir.mkdirs()
            }
            if (!resultFile.exists() && dir.isFile) {
                resultFile.createNewFile()
            }
            val file = File(selectPhotoPath!!)
            file.renameTo(resultFile)
        }

        chatAdapter.addMessage(
            ChatItem(
                GetAnswerResponse(answer = finalText, imagePath = resultFile?.absolutePath ?: ""),
                if (resultFile == null) ChatType.TYPE_QUESTION else ChatType.TYPE_PHOTO,
                false
            )
        )
        chatAdapter.addMessage(
            ChatItem(
                null,
                ChatType.TYPE_ANSWER,
                true
            )
        )
        isLoading = true
        val errorMsg = resources.getString(R.string.chat_default_errot_msg)
        viewModel.getAnswerWithPhoto(
            finalText,
            resultFile,
            chatAdapter.getLastConversationId(),
            errorMsg
        )
        binding.etChat.setText("")
        deletePhoto()
        setSendClickable(false)
    }

    private fun setSendClickable(clickable: Boolean) {
        binding.ivSend.isClickable = clickable
        if (clickable) {
            binding.ivSend.setImageResource(R.drawable.ic_chat_send)
        } else {
            binding.ivSend.setImageResource(R.drawable.ic_chat_send_grey)
        }
    }

    private fun setShareClickable(clickable: Boolean) {
        binding.ivShare.isClickable = clickable
        if (clickable) {
            binding.ivShare.setImageResource(R.drawable.ic_share)
        } else {
            binding.ivShare.setImageResource(R.drawable.ic_share_grey)
        }
    }

    private fun setIsGoingToBilling(isGoing: Boolean) {
        isGoingToBilling = isGoing
        binding.ivBack.setImageResource(
            if (isGoing) {
                R.drawable.ic_back_grey
            } else {
                R.drawable.ic_back
            }
        )
    }

    private fun doShowRewardDialog(isDueToSend: Boolean) {
        AnalyticsEvents.AC_POPUP_PAGE_SHOW.logEvent()

        rewardDialogFragment = RewardDialogFragment().apply {
            listener = object : RewardDialogFragment.OnDialogClickListener {
                override fun onRemoveLimits() {
                    AnalyticsEvents.AC_POPUP_SUB_CLICK.logEvent()

                    dismiss()
                    val intent = Intent(this@ChatActivity, BillingActivity::class.java).apply {
                        putExtra(
                            BillingActivity.KEY_VIP_TYPE, if (isDueToSend) {
                                AnalyticsParams.SEND_POPUP
                            } else {
                                AnalyticsParams.BUTTON_POPUP
                            }
                        )
                    }
                    setIsGoingToBilling(false)
                    startActivity(intent)
                }

                override fun onWatchAd() {
                    AnalyticsEvents.AC_POPUP_ADS_CLICK.logEvent()

                    watchRewardAd()
                }

                override fun onRewardCloseByUser() {
                    chatRewardCache.destroyAd()
                    binding.chatRecycler.removeCallbacks(destroyCallback)
                }

            }
        }
        rewardDialogFragment?.show(supportFragmentManager, "")
    }

    private fun watchRewardAd() {
        chatRewardCache.initRewardAdHelper(this)
        val mRewardedAdHelper = chatRewardCache.mRewardedAdHelper!!

        mRewardedAdHelper.setAdListener(object : RewardedAdListener() {
            override fun onAdLoaded() {
                mRewardedAdHelper.showAd(AdUtils.getChatRvAdConfig(this@ChatActivity).adPlacement)
                binding.chatRecycler.removeCallbacks(destroyCallback)
            }

            override fun onUserRewarded(p0: AdReward?) {
                ChatLimitUtils.addOneRemain()
                rewardDialogFragment?.dismissAllowingStateLoss()
                showLatestRemain()
                Toast.makeText(this@ChatActivity, R.string.reward_success, Toast.LENGTH_LONG)
                    .show()
                if (!chatAdapter.isLimitsEmpty()) {
                    chatAdapter.removeAllLimits()
                    doRegenerate()
                }
            }

            override fun onAdLoadFailed(p0: String?, p1: String?) {
                rewardDialogFragment?.setIsAdLoad(false)
                chatAdapter.notifyLimitsItemChanged(showAdLimits = true, isLoading = false)

                Toast.makeText(
                    this@ChatActivity,
                    resources.getString(R.string.reward_fail),
                    Toast.LENGTH_LONG
                ).show()
                binding.chatRecycler.removeCallbacks(destroyCallback)
            }

            override fun onAdDisplayed() {
                rewardDialogFragment?.setIsAdLoad(false)
                chatAdapter.notifyLimitsItemChanged(showAdLimits = true, isLoading = false)
            }

            override fun onAdDisplayFailed(p0: String?, p1: String?) {
                rewardDialogFragment?.setIsAdLoad(false)
                chatAdapter.notifyLimitsItemChanged(showAdLimits = true, isLoading = false)
                Toast.makeText(
                    this@ChatActivity,
                    resources.getString(R.string.reward_fail),
                    Toast.LENGTH_LONG
                ).show()
            }
        })

        if (mRewardedAdHelper.isReady) {
            mRewardedAdHelper.showAd(AdUtils.getChatRvAdConfig(this@ChatActivity).adPlacement)
            return
        }
        mRewardedAdHelper.loadAd(AdUtils.getChatRvAdConfig(this@ChatActivity).adPlacement)
        binding.chatRecycler.postDelayed(destroyCallback, 10_000L)
    }

    private fun showLatestRemain() {
        val count = ChatLimitUtils.getRemainCount()
        binding.tvRemain.text = if (count > 1) {
            String.format(resources.getString(R.string.message_remain_complex), count)
        } else {
            String.format(resources.getString(R.string.message_remain_single), count)
        }
        binding.tvRemain.setTextColor(
            resources.getColor(
                if (count >= 3) {
                    R.color.remain_up_three
                } else {
                    R.color.remain_below_three
                }
            )
        )
    }

    private fun selectPhoto(path: String) {
        binding.run {
            ivSelect.isVisible = false
            ivPhoto.isVisible = true
            ivDeletePhoto.isVisible = true
            Glide.with(this@ChatActivity)
                .load(path)
                .skipMemoryCache(true)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .into(ivPhoto)
            selectPhotoPath = path
        }
    }

    private fun deletePhoto() {
        binding.ivSelect.isVisible = true
        binding.ivPhoto.isVisible = false
        binding.ivDeletePhoto.isVisible = false
        selectPhotoPath = null
    }

    private fun doShowSelectDialogFragment() {
        selectDialogFragment = SelectPhotoBottomDialogFragment().apply {
            listener = object : SelectPhotoBottomDialogFragment.OnPhotoSelectListener {
                override fun onPhotoSelect(uri: String, from: String) {
                    AnalyticsEvents.AC_CHATAI_ADD_SUC.logEvent()
                    selectDialogFragment?.dismissAllowingStateLoss()
                    selectPhoto(uri)
                    photoFrom = from
                    binding.etChat.postDelayed(
                        { softKeyboardHelper.showSoftKeyboard(binding.etChat) }, 300L
                    )
                }
            }
        }
        selectDialogFragment?.show(supportFragmentManager, "")
    }

}